# coding:utf-8
from turtle import update
from PyQt6.QtCore import Qt, QUrl
from PyQt6.QtWidgets import (
    QHBoxLayout,
    QWidget,
    QFrame,
    QHBoxLayout,
    QTableWidgetItem,
    QPushButton,
    QFormLayout,
    QSpacerItem,
    QSizePolicy,
    QLabel,
)
from qfluentwidgets import (
    PushButton,
    TableWidget,
    MessageBoxBase,
    SubtitleLabel,
    LineEdit,
    SpinBox,
    SearchLineEdit,
    ComboBox,
    Slider,
)

from common.enum.stock_category_enum import StockCategoryEnum

from .base_gallery_view import GalleryInterface
from .common.translator import Translator
from .common.style_sheet import StyleSheet
from .common.signal_bus import signalBus
from common.enum.stock_status_enum import StockStatusEnum
from dto.stock_info_monitor import AntMonitorStockInfo

from service.stock_service import (
    StockMainService,
)


class AllStockListInterface(GalleryInterface):
    def __init__(self, parent=None):
        t = Translator()
        super().__init__(
            title=t.view, subtitle="qfluentwidgets.components.widgets", parent=parent
        )
        self.setObjectName("viewInterface")

        # 添加顶部搜索框
        self.topView = TopWidgetView(self)
        self.vBoxLayout.addWidget(self.topView)

        # 添加中间列表
        self.stockChat = TableFrame(self)
        self.vBoxLayout.addWidget(self.stockChat)


class SelfSearchLineEdit(SearchLineEdit):
    """Search line edit"""

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setPlaceholderText(self.tr("通过股票代码/名称查询"))
        self.setFixedWidth(304)
        self.textChanged.connect(self.search)


class TopWidgetView(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent=parent)

        # 顶部搜索框
        self.searchLineEdit = SelfSearchLineEdit(self)

        # 新增新股
        self.addButton = PushButton(self.tr("新增新股"))
        self.addButton.setFixedWidth(120)
        self.addButton.clicked.connect(self.showCustomDialog)

        #
        self.updateButton = PushButton(self.tr("刷新所有"))
        self.updateButton.setFixedWidth(120)

        self.spacer = QSpacerItem(
            20, 10, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum
        )

        self.hBoxLayout = QHBoxLayout()

        self.__initWidget()

    def __initWidget(self):

        self.hBoxLayout.setSpacing(0)
        self.hBoxLayout.setContentsMargins(0, 0, 0, 0)
        self.hBoxLayout.addWidget(self.searchLineEdit)
        self.hBoxLayout.addStretch(1)
        self.hBoxLayout.addWidget(self.addButton)

        self.hBoxLayout.addItem(self.spacer)
        self.hBoxLayout.addWidget(self.updateButton)

        self.searchLineEdit.clearSignal.connect(self.showAllIcons)
        self.searchLineEdit.searchSignal.connect(self.search)

        self.setLayout(self.hBoxLayout)

    def search(self, keyWord: str):
        AntLogger.info("查询所有股票")

    def showAllIcons(self):
        AntLogger.info("清空查询")

    def showCustomDialog(self):
        w = CustomMessageBox(self.window(), self)
        w.exec()


class Frame(QFrame):

    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.hBoxLayout = QHBoxLayout(self)
        self.hBoxLayout.setContentsMargins(0, 8, 0, 0)

        self.setObjectName("frame")
        StyleSheet.VIEW_INTERFACE.apply(self)

    def addWidget(self, widget):
        self.hBoxLayout.addWidget(widget)


class TableFrame(TableWidget):

    def __init__(self, parent=None):
        super().__init__(parent)

        self.verticalHeader().hide()
        self.setBorderRadius(8)
        self.setBorderVisible(True)

        self.setColumnCount(18)
        self.setRowCount(100)
        self.setHorizontalHeaderLabels(
            [
                "股票名称",
                "股票代码",
                "股票板块",
                "股票得分",
                "关注等级",
                "风险等级",
                "当前持股数",
                "最大持股数",
                "参考价格",
                "当前价格",
                "盈利比例",
                "盈利金额",
                "目标比例",
                "止损比例",
                "股票状态",
                "打标标签",
                "后续建议",
                "上涨天数",
                "操作方式",
            ]
        )

        self.refreshData()
        signalBus.dataSignal.connect(self.outRefreshData)

    def outRefreshData(self, type, data):
        self.refreshData()

    def refreshData(self):
        self.clearContents()
        stockMainService = StockMainService()
        self.stockList = stockMainService.getAllStockList()

        # 填充数据
        for row, stock in enumerate(self.stockList):
            self.setItem(row, 0, QTableWidgetItem(stock.stock_name))
            self.setItem(row, 1, QTableWidgetItem(stock.stock_code))
            self.setItem(row, 2, QTableWidgetItem(stock.stock_plates))
            self.setItem(row, 3, QTableWidgetItem(str(stock.stock_final_point or "")))
            self.setItem(row, 4, QTableWidgetItem(str(stock.stock_focus_level or "")))
            self.setItem(row, 5, QTableWidgetItem(str(stock.stock_risk_level or "")))
            self.setItem(row, 6, QTableWidgetItem(str(stock.stock_current_number or "")))
            self.setItem(row, 7, QTableWidgetItem(str(stock.stock_max_number or "")))
            self.setItem(row, 8, QTableWidgetItem(str(stock.monitor_origin_price or "")))
            self.setItem(row, 9, QTableWidgetItem(str(stock.monitor_current_price or "")))
            self.setItem(row, 10, QTableWidgetItem(str(stock.monitor_income_ratio or "")))
            self.setItem(row, 11, QTableWidgetItem(str(stock.monitor_income_money or "")))
            self.setItem(row, 12, QTableWidgetItem(str(stock.monitor_target_ratio or "")))
            self.setItem(row, 13, QTableWidgetItem(str(stock.monitor_stop_ratio or "")))
            self.setItem(row, 14, QTableWidgetItem(str(stock.stock_status or "")))
            self.setItem(row, 15, QTableWidgetItem(stock.stock_tag or ""))
            self.setItem(row, 16, QTableWidgetItem(stock.stock_next_advice or ""))
            self.setCellWidget(row, 17, self.create_buttons_widget(stock.stock_code))
        self.resizeColumnsToContents()

    def create_buttons_widget(self, stock_code):
        # 创建一个小部件用于容纳按钮
        widget = QWidget()

        # 创建布局
        layout = QHBoxLayout()

        # 创建第一个按钮
        btn1 = QPushButton("更新")
        btn1.clicked.connect(lambda: self.on_button_click("Edit", stock_code))
        layout.addWidget(btn1)

        # 创建第二个按钮
        btn2 = QPushButton("删除")
        btn2.clicked.connect(lambda: self.on_button_click("Delete", stock_code))
        layout.addWidget(btn2)

        # 创建第二个按钮
        btn3 = QPushButton("详情")
        btn3.clicked.connect(lambda: self.on_button_click("Detail", stock_code))
        layout.addWidget(btn3)

        # 将布局应用到小部件
        widget.setLayout(layout)
        return widget

    def on_button_click(self, action, row):
        if action == "Edit":
            AntLogger.info(f"Edit button clicked on row {row}")
            self.updateStock(row)
        elif action == "Delete":
            self.deleteOneStock(row)
        elif action == "Detail":
            AntLogger.info(f"查询详情 {row}")
            signalBus.switchToSampleCard.emit("StockDayView", 0, row)

    def deleteOneStock(self, stockCode):
        StockMainService().deleteOneStock(stockCode)
        signalBus.dataSignal.emit("refreshStockList", "")

    def updateStock(self, stockCode):
        w = CustomMessageBox(self.window(), self)
        stockInfo = StockMainService().getByStockCode(stockCode)
        w.updateStock(stockInfo)
        w.exec()


class CustomMessageBox(MessageBoxBase):
    """Custom message box"""

    def __init__(self, parent=None, outView=None):
        super().__init__(parent)

        self.outView = outView

        self.stockMainService = StockMainService()
        self.isUpate = False
        self.formItem = {}

        # 添加标题栏
        self.titleLabel = SubtitleLabel(self.tr("添加新股"), self)
        self.viewLayout.addWidget(self.titleLabel)
        self.formLayout = QFormLayout()
        self.formLayout.setVerticalSpacing(10)

        # 添加 LineEdit 控件
        self.add_line_edit_with_label(
            "股票代码", "stock_code", "请填写股票代码", "002670.SZ"
        )
        self.add_line_edit_with_label(
            "股票当前持股数", "current_number", "请填写当前持股数", ""
        )
        self.add_line_edit_with_label(
            "最大持股数", "max_number", "请填写最大持股数", ""
        )
        self.add_line_edit_with_label("参考价格", "origin_price", "请填写参考价格", "")

        # 添加 Slider 插件
        self.add_slider_with_label("盈利比例", "profit_ratio", 1, 50, 15)
        self.add_slider_with_label("目标比例", "target_ratio", 1, 50, 15)
        self.add_slider_with_label("止损比例", "stop_ratio", 1, 20, 10)

        # 录入股票状态
        self.statusComboBox = ComboBox(self)
        self.statusComboBox.addItems(StockStatusEnum.get_status_list())
        self.statusComboBox.setCurrentText(StockStatusEnum.get_default())  # 默认为持有
        self.formLayout.addRow("选择股票状态:", self.statusComboBox)

        # 选择股票分类
        self.categoryComboBox = ComboBox(self)
        self.categoryComboBox.addItems(StockCategoryEnum.get_category_list())
        self.categoryComboBox.setCurrentText(
            StockCategoryEnum.get_default()
        )  # 默认为个股
        self.formLayout.addRow("选择股票分类:", self.categoryComboBox)

        # 录入打标标签
        self.tagEdit = LineEdit(self)
        self.tagEdit.setPlaceholderText(self.tr("请填写打标标签"))
        self.formLayout.addRow("打标标签:", self.tagEdit)

        # 录入备注信息
        self.ohterEdit = LineEdit(self)
        self.ohterEdit.setPlaceholderText(self.tr("请填写备注"))
        self.formLayout.addRow("备注信息:", self.ohterEdit)

        self.viewLayout.addLayout(self.formLayout)

        # 提交
        self.yesButton.setText(self.tr("提交"))
        self.widget.setMinimumWidth(360)
        self.yesButton.setDisabled(False)
        self.yesButton.clicked.connect(self.submitForm)

    def add_slider_with_label(
        self, label: str, key: str, min_value: int, max_value: int, initial_value: int
    ):
        """
        动态创建滑轨及显示框，并添加到表单布局中。

        :param label: 滑轨的标签文本
        :param key: 滑轨的唯一键名，用于取值
        :param min_value: 滑轨的最小值
        :param max_value: 滑轨的最大值
        :param initial_value: 滑轨的初始值
        """
        slider = Slider(Qt.Orientation.Horizontal)
        slider.setRange(min_value, max_value)
        slider.setValue(initial_value)
        slider.setTickInterval(1)
        slider.setSingleStep(1)

        value_label = QLabel(str(initial_value))  # 显示滑轨初始值
        value_label.setFixedWidth(30)  # 固定宽度，避免动态改变时影响布局

        # 创建水平布局，将滑轨和显示框并排放置
        slider_layout = QHBoxLayout()
        slider_layout.addWidget(slider)
        slider_layout.addWidget(value_label)

        # 添加到表单布局
        self.formLayout.addRow(f"{label}:", slider_layout)

        # 存储控件引用
        self.formItem[key] = {
            "slider": slider,
            "label": value_label,
            "control": slider,
            "type": "slider",
        }

        # 连接滑轨值改变信号到槽函数，更新显示框的值
        slider.valueChanged.connect(lambda value: value_label.setText(str(value)))

    def add_line_edit_with_label(
        self, label: str, key: str, placeholder: str, initial_value: str = ""
    ):
        line_edit = LineEdit(self)
        line_edit.setPlaceholderText(self.tr(placeholder))
        line_edit.setText(initial_value)
        line_edit.setClearButtonEnabled(True)

        self.formItem[key] = {"control": line_edit, "type": "line_edit"}

        self.formLayout.addRow(f"{label}:", line_edit)

    def get_form_value(self, key: str) -> str | int:
        control_data = self.formItem.get(key)
        if not control_data:
            raise KeyError(f"控件 '{key}' 未找到！")

        control = control_data["control"]
        control_type = control_data["type"]

        if control_type == "line_edit":
            return control.text()
        elif control_type == "slider":
            return control.value()
        else:
            raise TypeError(f"未知控件类型 '{control_type}'")

    def set_value(self, key: str, value: str | int):
        # 通用方法，设置控件值
        control_data = self.formItem.get(key)
        if not control_data:
            raise KeyError(f"控件 '{key}' 未找到！")

        control = control_data["control"]
        control_type = control_data["type"]

        if control_type == "line_edit":
            if not isinstance(value, str):
                raise ValueError(
                    f"控件 '{key}' 的值类型应为 str，但收到 {type(value).__name__}"
                )
            control.setText(value)
        elif control_type == "slider":
            if not isinstance(value, int):
                raise ValueError(
                    f"控件 '{key}' 的值类型应为 int，但收到 {type(value).__name__}"
                )
            control.setValue(value)
        else:
            raise TypeError(f"未知控件类型 '{control_type}'")

    def _validateUrl(self):
        if self.codeEdit.text and self.priceEdit.text and self.ratioEdit.text:
            self.yesButton.setEnabled(True)

    # 滑动后更新显示的值
    def update_label(self, value):
        self.incomeLabel.setText(str(value))  # 更新显示框的值

    def submitForm(self):
        stock_info = AntMonitorStockInfo(
            stock_code=self.get_form_value("stock_code") or "",
            stock_current_number=int(self.get_form_value("current_number") or 0),
            stock_max_number=int(self.get_form_value("max_number") or 0),
            monitor_origin_price=float(self.get_form_value("origin_price") or 0),
            monitor_income_ratio=int(self.get_form_value("profit_ratio") or 0),
            monitor_target_ratio=int(self.get_form_value("target_ratio") or 0),
            monitor_stop_ratio=int(self.get_form_value("stop_ratio") or 0),
            stock_category=self.categoryComboBox.currentText(),
            stock_status=self.statusComboBox.currentText(),
            stock_tag=self.tagEdit.text(),
            other_info=self.ohterEdit.text(),
            is_update=self.isUpate,
        )
        if self.isUpate:
            self.stockMainService.updateMonitorStock(stock_info)
        else:
            self.stockMainService.saveMonitorStock(stock_info)

        signalBus.dataSignal.emit("refreshStockList", "")

    def updateStock(self, stock_data: AntMonitorStockInfo):
        self.set_value("stock_code", stock_data.stock_code or "")
        self.set_value("current_number", str(stock_data.stock_current_number or ""))
        self.set_value("max_number", str(stock_data.stock_max_number or ""))
        self.set_value("origin_price", str(stock_data.monitor_origin_price or ""))
        self.set_value("profit_ratio", int(stock_data.monitor_income_ratio or 1))
        self.set_value("target_ratio", int(stock_data.monitor_target_ratio or 0))
        self.set_value("stop_ratio", int(stock_data.monitor_stop_ratio or 0))
        self.statusComboBox.setCurrentText(stock_data.stock_status or "")
        self.categoryComboBox.setCurrentText(stock_data.stock_status or "")
        self.tagEdit.setText(stock_data.stock_tag or "")
        self.ohterEdit.setText(stock_data.other_info or "")
        self.isUpate = True


def calculate_target_profit(
    monitor_origin_price, stock_current_number, monitor_income_ratio
):
    # 计算目标盈利金额
    monitor_income_money = (
        monitor_origin_price * stock_current_number * (monitor_income_ratio / 100)
    )
    return monitor_income_money
